package cn.iocoder.yudao.module.aiposter.controller.app.poster;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.aiposter.config.PosterConfig;
import cn.iocoder.yudao.module.aiposter.controller.app.poster.vo.req.*;
import cn.iocoder.yudao.module.aiposter.controller.app.poster.vo.resp.AppPosterRespVO;
import cn.iocoder.yudao.module.aiposter.controller.app.poster.vo.resp.ImgRenderResp;
import cn.iocoder.yudao.module.aiposter.controller.app.poster.vo.resp.PosterGenerateRespVO;
import cn.iocoder.yudao.module.aiposter.dal.dataobject.poster.PosterDO;
import cn.iocoder.yudao.module.aiposter.remote.ImgClient;
import cn.iocoder.yudao.module.aiposter.service.poster.AppPosterService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.module.aiposter.enums.ErrorCodeConstants.IMG_UPLOAD_ERROR;

@Tag(name = "海报APP - Poster")
@RestController
@RequestMapping("/ai-poster/poster")
@Validated
public class AppPosterController {

    @Resource
    private PosterConfig posterConfig;

    @Resource
    private AppPosterService appPosterService;

    @Resource
    private ImgClient imgClient;

    @PostMapping("/render")
    @Operation(summary = "渲染海报")
    @PermitAll
    public CommonResult<String> renderImg(@Valid @RequestBody AppPosterRenderReqVO reqVO) {
        return success(appPosterService.renderImg(reqVO));
    }

    @PostMapping("/renderAll")
    @Operation(summary = "渲染全部海报")
    @PermitAll
    public CommonResult<List<ImgRenderResp>> renderImages(@Valid @RequestBody List<AppPosterRenderReqVO> reqVO) {
        return success(appPosterService.renderImagesAsync(reqVO));
    }

    @PostMapping("/renderAllSync")
    @Operation(summary = "渲染全部海报")
    @PermitAll
    public CommonResult<List<ImgRenderResp>> renderImagesSyn(@Valid @RequestBody List<AppPosterRenderReqVO> reqVO) {
        return success(appPosterService.renderImagesSync(reqVO));
    }

    @PostMapping("/generate")
    @Operation(summary = "生成海报")
    @PermitAll
    public CommonResult<List<PosterGenerateRespVO>> generate(@Valid @RequestBody PosterGenerateReqVO reqVO) {
        return success(appPosterService.generatePoster(reqVO));
    }

    @PostMapping("/generatePlus")
    @Operation(summary = "生成海报高级版")
    @PermitAll
    public CommonResult<List<PosterGenerateRespVO>> generatePlus(@Valid @RequestBody PosterGeneratePlusReqVO reqVO) {
        return success(appPosterService.generatePosterPlus(reqVO));
    }

    @PostMapping("/upload")
    @Operation(summary = "上传图片")
    @PermitAll
    public CommonResult<String> upload(@RequestParam("file") MultipartFile fileUpload) {
        // 上传图床
        try {
            String remotePath = imgClient.uploadNormalWithHttpUpload(fileUpload);
            return success(remotePath);
        }catch (IOException e){
            e.printStackTrace();
        }
        return error(IMG_UPLOAD_ERROR);
    }

    @PostMapping(value = "/segmentation", produces = MediaType.IMAGE_JPEG_VALUE)
    @Operation(summary = "抠图")
    @PermitAll
    @ResponseBody
    public byte[] segmentation(@RequestParam("file") MultipartFile fileUpload) {
        // 抠图
        return appPosterService.segmentation(fileUpload);
    }

    /**
     * 图片查看
     *
     * @return String
     */
    @Operation(summary = "查看图片")
    @PermitAll
    @GetMapping("/image/look/{filePath}")
    public String imageLook(@PathVariable(name = "filePath") String filePath, HttpServletResponse response) {
        String tmpFilePath = posterConfig.getLocalUploadDir();
        if (!filePath.startsWith("/")) {
            filePath = "//" + filePath;
        }
        File file = new File(tmpFilePath + filePath);
        byte[] bytes = new byte[1024];
        try (OutputStream os = response.getOutputStream();
             FileInputStream fis = new FileInputStream(file)) {
            while ((fis.read(bytes)) != -1) {
                os.write(bytes);
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "success";
    }


    @PostMapping("/create")
    @Operation(summary = "创建海报信息")
    public CommonResult<Long> create(@Valid @RequestBody AppPosterSaveReqVO createReqVO) {
        return success(appPosterService.create(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新海报信息")
    public CommonResult<Boolean> update(@Valid @RequestBody AppPosterSaveReqVO updateReqVO) {
        appPosterService.update(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除海报信息")
    @Parameter(name = "id", description = "编号", required = true)
    public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
        appPosterService.delete(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得海报信息")
    @PermitAll
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<AppPosterRespVO> get(@RequestParam("id") Long id) {
        PosterDO poster = appPosterService.get(id);
        return success(BeanUtils.toBean(poster, AppPosterRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得海报信息分页")
    public CommonResult<PageResult<AppPosterRespVO>> getPage(@Valid AppPosterPageReqVO pageReqVO) {
        PageResult<PosterDO> pageResult = appPosterService.getPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, AppPosterRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出海报信息 Excel")
    @OperateLog(type = EXPORT)
    public void exportExcel(@Valid AppPosterPageReqVO pageReqVO,
                            HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<PosterDO> list = appPosterService.getPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "海报信息.xls", "数据", AppPosterRespVO.class,
                BeanUtils.toBean(list, AppPosterRespVO.class));
    }
}
